package com.app.Controller;

import java.util.ArrayList;
import java.util.Iterator;

import it.unipr.ce.dsg.s2p.message.Payload;
import it.unipr.ce.dsg.s2p.org.json.JSONException;
import it.unipr.ce.dsg.s2p.org.json.JSONObject;
import it.unipr.ce.dsg.s2p.sip.Address;

import ReadWriteXML.CMember;
import android.app.Activity;
import android.app.Application;
import android.graphics.YuvImage;
import android.os.Handler;
import android.util.Log;

import com.app.Activity.frmBieuQuyetMoiRoiNhom;
import com.app.Activity.frmMainActivity;
import com.app.Activity.trucActivity;
import com.app.DTO.AccountDTO;
import com.app.DTO.RoleDTO;
import com.app.Network.NetworkLayer;
import com.app.Network.PingMessage;
import com.app.Network.Protocol;

public class NetworkController {

	public static NetworkLayer _peer = null;
	public static Handler handler = new Handler();
	public static Address sender;
	/**
	 * Phú Gửi lời mời vào nhóm
	 * 
	 * @param toAddress
	 *            : Địa chỉ muốn mời
	 * @param groupName
	 *            : Tên nhóm của mình
	 * @param msg
	 *            : Lời nhắn(mời)
	 * @return
	 */

	public static boolean sendGroupInvite(Address toAddress, String groupName, String msg) {

		Log.d("Phu", " vao ham sendGroupInvite");
		boolean rs = _peer.getAccount().getRule().get(0).getSend();

		if (rs) {
			PingMessage message = new PingMessage(_peer.getPeerDescriptor());
			message.setType(Protocol.GROUP_INVITE);
			Payload payload = new Payload();
			payload.addParam(Protocol.GROUP_INVITE_DATA_GROUP_NAME, groupName);
			payload.addParam(Protocol.GROUP_INVITE_DATA_MSG, msg);
			message.setPayload(payload);
			_peer.send(toAddress, message);
			Log.d("Phu","Da send sendGroupInvite to:"+toAddress.getHost()+":"+toAddress.getPort());
		} else {
			Log.d("Phu", "Ko co quyen  send GROUP_INVITE");
			handler.post(new Runnable() {
				@Override
				public void run() {
					ActivityController.showError();
				}
			});

		}
		return rs;
	}

	public static boolean sendDongYVaoNhom(Address toAddress) {
		PingMessage msg = new PingMessage(_peer.getPeerDescriptor());
		msg.setType(Protocol.GROUP_INVITE_REPLY_YES);
		_peer.send(new Address(toAddress), msg);
		Log.d("Phu","Da send sendDongYVaoNhom to:"+toAddress.getHost()+":"+toAddress.getPort());
		return true;
	}

	public static boolean sendKhongChoVaoNhom(Address toAddress) {
		PingMessage msg = new PingMessage(_peer.getPeerDescriptor());
		msg.setType(Protocol.GROUP_INVITE_NO);
		_peer.send(new Address(toAddress), msg);
		Log.d("Phu","Da send sendKhongChoVaoNhom to:"+toAddress.getHost()+":"+toAddress.getPort());
		return true;
	}

	public static boolean sendChoVaoNhom(Address toAddress) {
		PingMessage msg = new PingMessage(_peer.getPeerDescriptor());
		msg.setType(Protocol.GROUP_INVITE_YES);
		_peer.send(new Address(toAddress), msg);
		Log.d("Phu","Da send sendChoVaoNhom to:"+toAddress.getHost()+":"+toAddress.getPort());
		return true;

	}

	public static boolean sendSetRole(Address toAddress, ArrayList<RoleDTO> roleList) {
		PingMessage msg = new PingMessage(_peer.getPeerDescriptor());

		Payload payload = new Payload();
		payload.addParam("DATA", RoleDTO.toStringList(roleList));
		msg.setType(Protocol.SET_ROLE);
		msg.setPayload(payload);
		_peer.send(toAddress, msg);
		Log.d("Phu","Da send sendSetRole to:"+toAddress.getHost()+":"+toAddress.getPort());
		return true;
	}

	public static boolean sendJoinGroup(Address toAddress, String userName, String fullName) {
		PingMessage msg = new PingMessage(_peer.getPeerDescriptor());
		
		Payload payload = new Payload();
		payload.addParam(Protocol.MEMBER_FULL_NAME, fullName);
		payload.addParam(Protocol.MEMBER_USER_NAME, userName);
		
		msg.setType(Protocol.JOIN_GROUP);
		msg.setPayload(payload);
		_peer.send(toAddress, msg);
		Log.d("Phu","Da send sendJoinGroup to:"+toAddress.getHost()+":"+toAddress.getPort());
		return true;
	}
public static boolean sendUpdateMember(Address toAddress, CMember member){
	PingMessage msg = new PingMessage(_peer.getPeerDescriptor());
	
	Payload payload = new Payload();
	payload.addParam(Protocol.UPDATE_MEMBER_LIST, member.toParse());
	msg.setType(Protocol.UPDATE_MEMBER_LIST);
	msg.setPayload(payload);
	_peer.send(toAddress, msg);
	Log.d("Phu","Da send sendUpdateMember to:"+toAddress.getHost()+":"+toAddress.getPort());
	return true;
}
	public static boolean sendMemberList(Address toAddress, ArrayList<CMember> memberList) {
		
		PingMessage msg = new PingMessage(_peer.getPeerDescriptor());		
		Payload payload = new Payload();
		payload.addParam(Protocol.MEMBER_LIST, CMember.toParseList(memberList));		
		msg.setType(Protocol.MEMBER_LIST);
		msg.setPayload(payload);
		_peer.send(toAddress, msg);
		Log.d("Phu","Da send sendMemberList to:"+toAddress.getHost()+":"+toAddress.getPort()+"/data: "+CMember.toParseList(memberList));
		return true;
	}
	// ========================================truc===============================================

	// tao lao==========

	public static void SendHelloDLG(Address toAdd) {
		PingMessage m = new PingMessage(_peer.getPeerDescriptor());
		m.setType(Protocol.HELLO);
		_peer.send(toAdd, m);

	}

	public static void ShowForm1() {
		handler.post(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				ActivityController.ShowFrm1();
			}
		});
	}

	public static void ShowForm2() {
		handler.post(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				ActivityController.ShowFrm2();
			}
		});
	}

	// tao lao================

	// Quyền : 0:Chat, 1:Cam ngkhac noi, 2: moi nguoi khac ra khoi nhom
	public static void ShowMessageNotice(final String message) {
		handler.post(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub

				ActivityController.ShowMessage(message);
			}
		});
	}

	public static void ShowMessageChat(final String content, final String Address) {
		handler.post(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub

				ActivityController.ShowChatMessage(content, Address);
			}
		});
	}

	public static void DislayVoteKickMember() {
		handler.post(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				ActivityController.DislayKickMember();
			}
		});
	}

	public static void DislayResultVoteKick() {
		handler.post(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				ActivityController.ShowResultVote();
			}
		});
	}

	public static void doEndTimeKick() {
		handler.post(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				ActivityController.DoEndTime();
			}
		});
	}

	public static void GuiYeuCauNgungNoi(Address toAdd) {
		Log.d("Phu", "vao Controller ngung noi");
		boolean YourRule = _peer.getAccount().getRule().get(1).getSend();
		if (YourRule) {
			Log.d("Phu", "vao if ngung noi");
			PingMessage mess = new PingMessage(_peer.getPeerDescriptor());
			mess.setType(Protocol.STOP_TALKING_ONE_MEMBER);

			// String message="Ban da bi ngung noi";
			_peer.send(new Address(toAdd), mess);
			Log.d("Phu", "gui yeu cau ngung noi");
		} else {
			Log.d("Phu", "ko get dc quyen");
			NetworkController.ShowMessageNotice(Protocol.NON_RULE_MESSAGE);
		}
	}
	public static void GuiYeuCauNgungNoi(final Address toAdd,int time){
		Log.d("Phu","vao Controller ngung noi");
		boolean YourRule=_peer.getAccount().getRule().get(1).getSend();
		if (YourRule) {
			Log.d("Phu","vao if ngung noi");
			PingMessage mess=new PingMessage(_peer.getPeerDescriptor());
			mess.setType(Protocol.STOP_TALKING_ONE_MEMBER);
			Payload pl=new Payload();
			pl.addParam("TimeStopTalk", time);
			mess.setPayload(pl);
			//String message="Ban da bi ngung noi";
			_peer.send(new Address(toAdd), mess);
			
			Log.d("Phu","gui yeu cau ngung noi");
		}else{
			Log.d("Phu","ko get dc quyen");
			NetworkController.ShowMessageNotice(Protocol.NON_RULE_MESSAGE);


		}

	}
	public static void GuiTinNhanChat(Address toAddress, String content) {
		boolean YourRule = _peer.getAccount().getRule().get(0).getSend();
		if (YourRule) {
			Log.d("Phu", "vao if gui tin nhan");
			PingMessage mess = new PingMessage(_peer.getPeerDescriptor());
			mess.setType(Protocol.CHAT_MESSAGE);
			Payload pl = new Payload();
			pl.addParam("Content_Chat", content);
			mess.setPayload(pl);
			// String message="Ban da bi ngung noi";
			_peer.send(new Address(toAddress), mess);
			ActivityController.ShowChatMessage(content, _peer.getAddressPeer().toString());
			Log.d("Phu", "gui tin nhan");
		} else {
			Log.d("Phu", "ko get dc quyen");
			NetworkController.ShowMessageNotice(Protocol.NON_RULE_MESSAGE);
		}
	}

	public static void GuiPhanHoiKhongCoQuyenChat(Address toAddress) {
		Log.d("Phu", "gui phan hoi ko co quyen chat");
		PingMessage message = new PingMessage(_peer.getPeerDescriptor());
		message.setType(Protocol.CHAT_FEDBACK_NON_RULE);
		Payload pl = new Payload();
		// String s=_peer.getAccount().get_Username().toString();
		// pl.addParam("Content",
		// s+" không có quyền nhận tin nhắn trò chuyện.");
		pl.addParam("Content", "đối phương không có quyền nhận tin nhắn trò chuyện.");
		message.setPayload(pl);
		_peer.send(new Address(toAddress), message);
	}

	public static void GuiChoPhepNoiChuyen(Address toAddress) {
		Log.d("Phu", "vao Controller cho phep noi");
		boolean YourRule = _peer.getAccount().getRule().get(1).getSend();
		if (YourRule) {
			Log.d("Phu", "vao if cho noi");
			PingMessage message = new PingMessage(_peer.getPeerDescriptor());
			message.setType(Protocol.ACCEPT_TALKING_ONE_MEMBER);
			_peer.send(new Address(toAddress), message);
			Log.d("Phu", "gui yeu cau cho noi");
		} else {
			Log.d("Phu", "ko get dc quyen");
			NetworkController.ShowMessageNotice(Protocol.NON_RULE_MESSAGE);
		}
	}

	// gửi thông báo cần biểu quyết để mời 1 thành viên ra khỏi nhóm
	public static void SendVoteKickMember(Address toAddress, Address beingKick, int time) {
		Log.d("Phu", "vao send vote");		
		boolean yourRule = _peer.getAccount().getRule().get(2).getSend();
		if (yourRule) {
			Log.d("Phu", "vao if send vote");
			PingMessage message = new PingMessage(_peer.getPeerDescriptor());
			message.setType(Protocol.KICK_MEMBER_OUT_MESSAGE);
			Payload pl = new Payload();

			pl.addParam("Time", time);
			pl.addParam("IPBeingKick", beingKick.getURL());
			Log.d("Phu", "ip bi kick " + beingKick.getURL());
			message.setPayload(pl);
			_peer.send(toAddress, message);
			Log.d("Phu", "da send vote");
		} else {
			NetworkController.ShowMessageNotice(Protocol.NON_RULE_MESSAGE);
		}
	}

	// gửi ý kiến biểu quyết về việc mời 1 thành viên ra khỏi nhóm
	public static void SendFedbackKickMember(Address toAddress, int vote) {
		Log.d("Phu", "vao ham bieu quyet kick");
		// int vote=frmBieuQuyetMoiRoiNhom.YKienBieuQuyet;
		Log.d("Phu", "bieu quyet kick = " + vote);
		boolean yourRule = _peer.getAccount().getRule().get(3).getSend();
		if (yourRule) {
			Log.d("Phu", "vao if bieu quyet kick");
			PingMessage message = new PingMessage(_peer.getPeerDescriptor());
			message.setType(Protocol.KICK_MEMBER_OUT_FEDBACK);
			Payload pl = new Payload();
			if (vote == 1) {
				Log.d("Phu", " bieu quyet kick = yes");
				pl.addParam("VOTE", "1");
			} else if (vote == 0) {
				Log.d("Phu", " bieu quyet kick = no");
				pl.addParam("VOTE", "0");
			} else {
				Log.d("Phu", " bieu quyet kick = khac");
			}
			message.setPayload(pl);
			_peer.send(toAddress, message);
		} else {

			NetworkController.ShowMessageNotice("bạn không có quyền biểu quyết kick");
			Log.d("Phu", "ko co quyen bieu quyet kick");
		}
	}

	// hàm gửi kết quả cuoi cung ve moi nguoi khac ra khoi nhom
	public static void SendResultVoteKickMember(Address toAdd, int result, Address beingKickAdd) {
		Log.d("Phu","vao ham SendResultVoteKickMember" );
		boolean yourRule = _peer.getAccount().getRule().get(3).getSend();
		if (yourRule) {
			Log.d("Phu", "vao if send result kick");
			PingMessage message = new PingMessage(_peer.getPeerDescriptor());
			message.setType(Protocol.KICK_MEMBER_OUT_RESULT);
			Payload pl = new Payload();

			pl.addParam("Result", result);
			pl.addParam("BeingKick", beingKickAdd.getURL());
			message.setPayload(pl);
			_peer.send(toAdd, message);
			Log.d("Phu", "da send result kick");
		}
	}

	public static void CloseActivity() {
		handler.post(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				ActivityController.FinishDiscussActivity();
			}
		});
	}
	
	// =====end truc==================================================

	public static void init(String name, int port, AccountDTO account) {
		_peer = new NetworkLayer(null, "4654amv65d4as4d65a4", name, port, account);
	}
	//---------An
	//Ham Send Group Sign Out
	public static boolean sendGroupSignOut(String toAddress){
		boolean rs=_peer.getAccount().getRule().get(1).getSend();
		Log.d("PEERDROID","sign out send :" + String.valueOf(rs));
		if(rs){
			PingMessage message=new PingMessage(_peer.getPeerDescriptor());
			message.setType(Protocol.GROUP_SIGN_OUT);
			_peer.send(new Address(toAddress), message);
			Log.d("PEERDROID", "send group sign out...");
		}
		else{
			handler.post(new Runnable() {
				
				@Override
				public void run() {
					Log.d("PEERDROID", "loi send group sign out...");
					ActivityController.show_Error();
				}
			});
		}
		return rs;
	}
	
	//Ham Send Group Danh Gia
	public static boolean sendGroupDanhGia(String toAddress){
		boolean rs=_peer.getAccount().getRule().get(2).getSend();
		Log.d("PEERDROID"," send :" + String.valueOf(rs));
		if(rs){
			PingMessage message=new PingMessage(_peer.getPeerDescriptor());
			message.setType(Protocol.GROUP_DANH_GIA);
			_peer.send(new Address(toAddress), message);
			Log.d("PEERDROID", "send group danh gia..");
		}
		else{
			handler.post(new Runnable() {
				@Override
				public void run() {
					Log.d("PEERDROID", "loi send group danh gia...");
					ActivityController.show_Error();
				}
			});
		}
		return rs;
	}
	
	//Ham Send Result Danh Gia
	public static boolean sendResultDanhGia(String toAddress, String result){
		boolean rs=_peer.getAccount().getRule().get(2).getSend();
		Log.d("PEERDROID"," send :" + String.valueOf(rs));
		if(rs){
			Payload p = new Payload();
			p.addParam("RESULT", result);
			PingMessage message=new PingMessage(_peer.getPeerDescriptor());
			message.setType(Protocol.RESULT_DANH_GIA);
			message.setPayload(p);
			_peer.send(new Address(toAddress), message);
			Log.d("PEERDROID", "send result danh gia...");
		}
		else{
			handler.post(new Runnable() {
				@Override
				public void run() {
					Log.d("PEERDROID", "loi send result danh gia...");
					ActivityController.show_Error();
				}
			});
		}
		return rs;
	}
	
	//Ham Send Group Bieu Quyet
	public static boolean sendGroupBieuQuyet(String toAddress, int index, int time){
		boolean rs=_peer.getAccount().getRule().get(3).getSend();
		Log.d("PEERDROID"," send :" + String.valueOf(rs));
		if(rs){
			Payload p = new Payload();
			p.addParam("INDEX", index);
			p.addParam("TIME", time);
			PingMessage message=new PingMessage(_peer.getPeerDescriptor());
			message.setType(Protocol.GROUP_BIEU_QUYET);
			message.setPayload(p);
			_peer.send(new Address(toAddress), message);
			Log.d("PEERDROID", "send group bieu quyet...");
		}
		else{
			handler.post(new Runnable() {
				@Override
				public void run() {
					Log.d("PEERDROID", "loi send group bieu quyet...");
					ActivityController.show_Error();
					
				}
			});
		}
		return rs;
	}
	
	//Ham Send Result Bieu Quyet
	public static boolean sendResultBieuQuyet(String toAddress, int index, int value){
		boolean rs=_peer.getAccount().getRule().get(3).getSend();
		Log.d("PEERDROID"," send :" + String.valueOf(rs));
		if(rs){
			Payload p = new Payload();
			p.addParam("INDEX", index);
			p.addParam("VALUE", value);
			PingMessage message=new PingMessage(_peer.getPeerDescriptor());
			message.setType(Protocol.RESULT_BIEU_QUYET);
			message.setPayload(p);
			_peer.send(new Address(toAddress), message);
			Log.d("PEERDROID", "send ket qua bieu quyet...");
		}
		else{
			handler.post(new Runnable() {
				@Override
				public void run() {
					Log.d("PEERDROID", "loi send ket qua bieu quyet...");
					ActivityController.show_Error();
					
				}
			});
		}
		return rs;
	}
	
	//***************************
	//
	//------ Cac Ham Receive ----
	//
	//***************************
	
	//Receive Bieu Quyet
	public static void ReceiveBieuQuyet(JSONObject params, final Address sender) {
		
		Iterator<String> iter = params.keys();
		final int index;
		int i = 0;
		int time = 0;
		while(iter.hasNext()){

			String key = iter.next();
			String s = null;
			try {
				s = params.get(key).toString();
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if(key.equals("INDEX"))
			{
				
				i = Integer.valueOf(s);
			}
			if(key.equals("TIME"))
			{
				
				time = Integer.valueOf(s);
			}
		}
		//frmBieuQuyetActivity.timeVote = time;
		index = i;
		Log.d("PEERDROID","index " + index);
		Log.d("PEERDROID","trươc handler..........");
		ActivityController.hander.post(new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				Log.d("PEERDROID","vao handler..........");
				trucActivity.showNotificationBieuQuyet(index, sender);
			}
		});
		Log.d("PEERDROID","vao ham ReceiveBieuQuyet");
	}
	
	//Receive Result Danh gia
	public static void ReceiveResultDanhGia(JSONObject params, final Address sender) {
		Log.d("PEERDROID","vao ham ReceiveResultDanhGia");
		Iterator<String> iter = params.keys();
		final String result;
		String str= "";
		while(iter.hasNext()){

			String key = iter.next();
			String s = null;
			try {
				s = params.get(key).toString();
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if(key.equals("RESULT")){
				str = s;
			}
		}
		result = str;
		Log.d("PEERDROID","Ket qua: "+result);
		handler.post(new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				ActivityController.CountResultDanhGia(result);
			}
		});
	}
	
	//Ham receive Result Bieu Quyet
	public static void ReceiveResultBieuQuyet(JSONObject params, final Address sender) {
		Log.d("PEERDROID","vao ham ReceiveResultDanhGia");
		Iterator<String> iter = params.keys();
		final int index;
		final int value;
		int in = 0;
		int va = 0;
		while(iter.hasNext()){

			String key = iter.next();
			String s = null;
			try {
				s = params.get(key).toString();
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if(key.equals("INDEX")){
				Log.d("PEERDROID","index: "+s);
				in = Integer.parseInt(s);
			}
			if(key.equals("VALUE")){
				Log.d("PEERDROID","value: "+s);
				va = Integer.parseInt(s);
			}
		}
		index = in;
		value = va;
		handler.post(new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				ActivityController.CountResultBieuQuyet(index, value);
			}
		});
	}
	/**
	 * Đặt lại vai trò cho account<br>
	 * 		1.Reset role<br>
	 * 		2.Đọc role từ file lên
	 */
	public static void resetRole() {		 
		_peer.account.resetRole();
		ArrayList<RoleDTO> roleList = ReadWriteFileController
				.readRole(ReadWriteFileController.MY_ROLE_PATH);
		for (RoleDTO role : roleList) {
			_peer.account.addRole(role);
		}
	}
	public static boolean getIsThanhLapNhom(){
		return _peer.account.isThanhLapNhom;
	}
}
